package sam.learn.framework.dynamicDataSource;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sam.learn.biz.datasource.controller.dto.DataSourceInfoVo;
import sam.learn.biz.datasource.repo.entity.DatasourceInfo;
import sam.learn.biz.datasource.service.DatasourceInfoService;

import javax.sql.DataSource;
import java.util.List;

@Component
public class DbDynamicDataSourceLoader {


    @Value("${spring.datasource.dynamic.primary}")
    private String primaryDataSourceName;

    @Autowired
    @Qualifier("hikariDataSourceCreator")
    private DataSourceCreator dataSourceCreator;


    //核心动态数据源组件
    @Autowired
    private DynamicRoutingDataSource dynamicRoutingDataSource;

    @Autowired
    private DatasourceInfoService datasourceInfoService;


    public void loadDatasourceBy(String regionCode) {
        DatasourceInfo datasourceBy = datasourceInfoService.getDatasourceBy(regionCode);
        initDatasource(CollUtil.newArrayList(datasourceBy));
    }

    public void loadAllDatasource() {
        List<DatasourceInfo> datasourceInfoList = datasourceInfoService.loadAllDatasourceInfo();
        initDatasource(datasourceInfoList);
    }

    public void removeDatasourceBy(String regionCode) {
        dynamicRoutingDataSource.removeDataSource(regionCode);
    }

    private void initDatasource(List<DatasourceInfo> datasourceInfoList) {
        DataSource primaryDataSource = dynamicRoutingDataSource.getDataSource(primaryDataSourceName);

        datasourceInfoList
                .stream()
                .map(DataSourceInfoVo::from)
                .forEach(
                        item -> {
                            DataSourceProperty dsProperty = new DataSourceProperty();
                            //copy 主数据源属性
                            BeanUtils.copyProperties(primaryDataSource, dsProperty);
                            //修改数据库连接
                            dsProperty.setDriverClassName(item.getDriverClassName());
                            dsProperty.setUrl(item.getUrl());
                            dsProperty.setUsername(item.getUser());
                            dsProperty.setPassword(item.getPwd());
                            //创建数据源
                            DataSource dataSource = dataSourceCreator.createDataSource(dsProperty);
                            //加入到数据源容器内
                            dynamicRoutingDataSource.addDataSource(item.getRegionCode(), dataSource);
                        }
                );
    }

}
